package com.zerowidth.moc.web.utils;


import java.util.ArrayList;
import java.util.List;

public class MathUtil {

    public static int safe(int target, int min, int max) {
        return Math.min(max, Math.max(min, target));
    }

    public static long safe(long target, int min, int max) {
        return Math.min(max, Math.max(min, target));
    }

    public static int safeCycleForward(int target, int min, int max) {
        if (target == max) {
            return min;
        }
        return Math.min(max, Math.max(min, target));
    }

    public static int random(int fromInclude, int toExclude) {
        int random = (int) (Math.random() * (toExclude - fromInclude)) + fromInclude;
        return random;
    }

    /**
     * 将入参数组，随机重新排序后返回
     */
    public static int[] randomSort(int... a) {
        List<Integer> randomSortList = new ArrayList<>();
        for (int i = 0; i < a.length; i++) {
            randomSortList.add(a[i]);
        }

        int[] result = new int[a.length];

        for (int i = randomSortList.size() - 1; i >= 0; i--) {
            int random = (int) (Math.random() * randomSortList.size());
            result[i] = randomSortList.remove(random);
        }

        return result;
    }

    public static int randomFrom(int... a) {
        int index = (int) (Math.random() * a.length);

        return a[index];
    }

    public static <T> T randomFrom(List<T> list) {
        int index = (int) (Math.random() * list.size());

        return list.get(index);
    }

    /**
     * @param targetArr      随机可选的数值范围
     * @param probabilityArr 对应数值出现频率的权重，必须大于等于0
     * @return 随机值 或 -1表示出错
     */
    public static int randomSelect(int[] targetArr, int[] probabilityArr) {
        if (targetArr == null || probabilityArr == null || targetArr.length != probabilityArr.length) {
            return -1;
        }

        int[] nodeArr = new int[probabilityArr.length + 1];

        nodeArr[0] = 0;
        for (int i = 0; i < probabilityArr.length; i++) {
            nodeArr[i + 1] = CollectionUtil.sum(probabilityArr, i);
        }

        int weightTotal = CollectionUtil.sum(probabilityArr);
        int randomNodeIndex = (int) (Math.random() * weightTotal);

        for (int i = 0; i < nodeArr.length; i++) {
            if (randomNodeIndex >= nodeArr[i] && randomNodeIndex < nodeArr[i + 1]) {
                return targetArr[i];
            }
        }

        return -1;
    }

}
